Add support for win32 theme colors as symbolic colors
authorAlexander Larsson <alexl@redhat.com>
Fri, 18 Nov 2011 09:16:38 +0000 (10:16 +0100)
committerAlexander Larsson <alexl@redhat.com>
Fri, 18 Nov 2011 09:16:38 +0000 (10:16 +0100)
gtk/gtkcssparser.c
gtk/gtksymboliccolor.c
gtk/gtksymboliccolor.h
gtk/gtkwin32theme.c
gtk/gtkwin32themeprivate.h

index 2d6a4df3d007da34419efd087b9365dc15bcf708..ff44c35748d3691e1536c34ee179e643d443c9ee 100644 (file)
@@ -20,6 +20,7 @@
 #include "config.h"
 
 #include "gtkcssparserprivate.h"
+#include "gtkwin32themeprivate.h"
 
 #include <errno.h>
 #include <string.h>
@@ -575,7 +576,8 @@ typedef enum {
   COLOR_DARKER,
   COLOR_SHADE,
   COLOR_ALPHA,
-  COLOR_MIX
+  COLOR_MIX,
+  COLOR_WIN32
 } ColorType;
 
 static GtkSymbolicColor *
@@ -644,6 +646,12 @@ gtk_css_parser_read_symbolic_color_function (GtkCssParser *parser,
       
       symbolic = gtk_symbolic_color_new_literal (&rgba);
     }
+  else if (color == COLOR_WIN32)
+    {
+      symbolic = _gtk_win32_theme_color_parse (parser);
+      if (symbolic == NULL)
+       return NULL;
+    }
   else
     {
       child1 = _gtk_css_parser_read_symbolic_color (parser);
@@ -769,7 +777,8 @@ _gtk_css_parser_read_symbolic_color (GtkCssParser *parser)
 {
   GtkSymbolicColor *symbolic;
   guint color;
-  const char *names[] = {"rgba", "rgb",  "lighter", "darker", "shade", "alpha", "mix" };
+  const char *names[] = {"rgba", "rgb",  "lighter", "darker", "shade", "alpha", "mix",
+                        GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME};
   char *name;
 
   g_return_val_if_fail (GTK_IS_CSS_PARSER (parser), NULL);
index 41a81a1cabcc36470580678bf68878dded5e79e3..8f44966d9209705c473459267ec9e0f4fc033e42 100644 (file)
@@ -21,6 +21,7 @@
 #include "gtksymboliccolor.h"
 #include "gtkstyleproperties.h"
 #include "gtkintl.h"
+#include "gtkwin32themeprivate.h"
 
 /**
  * SECTION:gtksymboliccolor
@@ -50,7 +51,8 @@ typedef enum {
   COLOR_TYPE_NAME,
   COLOR_TYPE_SHADE,
   COLOR_TYPE_ALPHA,
-  COLOR_TYPE_MIX
+  COLOR_TYPE_MIX,
+  COLOR_TYPE_WIN32
 } ColorType;
 
 struct _GtkSymbolicColor
@@ -75,6 +77,12 @@ struct _GtkSymbolicColor
       GtkSymbolicColor *color2;
       gdouble factor;
     } mix;
+
+    struct
+    {
+      gchar *theme_class;
+      gint id;
+    } win32;
   };
 };
 
@@ -226,6 +234,35 @@ gtk_symbolic_color_new_mix (GtkSymbolicColor *color1,
   return symbolic_color;
 }
 
+/**
+ * gtk_symbolic_color_new_mix: (constructor)
+ * @theme_class: The theme class to pull color from
+ * @id: The color id
+ *
+ * Creates a symbolic color based on the current win32
+ * theme.
+ *
+ * Returns: A newly created #GtkSymbolicColor
+ *
+ * Since: 3.4
+ **/
+GtkSymbolicColor *
+gtk_symbolic_color_new_win32 (const gchar        *theme_class,
+                             gint                id)
+{
+  GtkSymbolicColor *symbolic_color;
+
+  g_return_val_if_fail (theme_class != NULL, NULL);
+
+  symbolic_color = g_slice_new0 (GtkSymbolicColor);
+  symbolic_color->type = COLOR_TYPE_WIN32;
+  symbolic_color->win32.theme_class = g_strdup (theme_class);
+  symbolic_color->win32.id = id;
+  symbolic_color->ref_count = 1;
+
+  return symbolic_color;
+}
+
 /**
  * gtk_symbolic_color_ref:
  * @color: a #GtkSymbolicColor
@@ -279,6 +316,9 @@ gtk_symbolic_color_unref (GtkSymbolicColor *color)
           gtk_symbolic_color_unref (color->mix.color1);
           gtk_symbolic_color_unref (color->mix.color2);
           break;
+        case COLOR_TYPE_WIN32:
+          g_free (color->win32.theme_class);
+          break;
         default:
           break;
         }
@@ -556,6 +596,12 @@ gtk_symbolic_color_resolve (GtkSymbolicColor   *color,
         return TRUE;
       }
 
+      break;
+    case COLOR_TYPE_WIN32:
+      return _gtk_win32_theme_color_resolve (color->win32.theme_class,
+                                            color->win32.id,
+                                            resolved_color);
+
       break;
     default:
       g_assert_not_reached ();
@@ -623,6 +669,12 @@ gtk_symbolic_color_to_string (GtkSymbolicColor *color)
         g_free (color_string2);
       }
       break;
+    case COLOR_TYPE_WIN32:
+      {
+        s = g_strdup_printf (GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME"(%s, %d)", 
+                            color->win32.theme_class, color->win32.id);
+      }
+      break;
     default:
       g_assert_not_reached ();
     }
index 7be051a866d99a20a377bc8560865368d9919120..6bb4e76f7cc4d05e9a014128a86bb86bfea24d8f 100644 (file)
@@ -42,6 +42,8 @@ GtkSymbolicColor * gtk_symbolic_color_new_alpha   (GtkSymbolicColor   *color,
 GtkSymbolicColor * gtk_symbolic_color_new_mix     (GtkSymbolicColor   *color1,
                                                    GtkSymbolicColor   *color2,
                                                    gdouble             factor);
+GtkSymbolicColor * gtk_symbolic_color_new_win32   (const gchar        *theme_class,
+                                                  gint                id);
 
 GtkSymbolicColor * gtk_symbolic_color_ref         (GtkSymbolicColor   *color);
 void               gtk_symbolic_color_unref       (GtkSymbolicColor   *color);
index 5c4720dc5ab2660550c1957ca353b1ccd3bc5d5c..fb5bb4790383f97d101989d3f206d8392b9251c0 100644 (file)
@@ -490,3 +490,67 @@ _gtk_win32_theme_int_parse (GtkCssParser      *parser,
 
   return -1;
 }
+
+GtkSymbolicColor *
+_gtk_win32_theme_color_parse (GtkCssParser *parser)
+{
+  GtkSymbolicColor *color;
+  char *class;
+  int id;
+
+  class = _gtk_css_parser_try_name (parser, TRUE);
+  if (class == NULL)
+    {
+      _gtk_css_parser_error (parser,
+                            "Expected name as first argument to  '-gtk-win32-color'");
+      return NULL;
+    }
+
+  if (! _gtk_css_parser_try (parser, ",", TRUE))
+    {
+      g_free (class);
+      _gtk_css_parser_error (parser,
+                            "Expected ','");
+      return NULL;
+    }
+
+  if (!_gtk_css_parser_try_int (parser, &id))
+    {
+      g_free (class);
+      _gtk_css_parser_error (parser, "Expected a valid integer value");
+      return NULL;
+    }
+
+  color = gtk_symbolic_color_new_win32 (class, id);
+  g_free (class);
+  return color;
+}
+
+gboolean
+_gtk_win32_theme_color_resolve (const char *theme_class,
+                               gint id,
+                               GdkRGBA *color)
+{
+#ifdef G_OS_WIN32
+  DWORD dcolor;
+
+  if (use_xp_theme && get_theme_sys_color != NULL)
+    {
+      HTHEME theme = lookup_htheme_by_classname (theme_class);
+
+      /* if theme is NULL, it will just return the GetSystemColor()
+         value */
+      dcolor = get_theme_sys_color (theme, id);
+    }
+  else
+    dcolor = GetSysColor (id);
+
+  color->alpha = 1.0;
+  color->red = GetRValue (dcolor) / 255.0;
+  color->green = GetGValue (dcolor) / 255.0;
+  color->blue = GetBValue (dcolor) / 255.0;
+#else
+  gdk_rgba_parse (color, "pink");
+#endif
+  return TRUE;
+}
index 166c67053b7f5438ab9020a42a25f18ecc1edffe..25349d2e377d64d20c0daf9c8b7bb583eef580af 100644 (file)
@@ -26,6 +26,8 @@
 
 G_BEGIN_DECLS
 
+#define GTK_WIN32_THEME_SYMBOLIC_COLOR_NAME "-gtk-win32-color"
+
 typedef struct _GtkWin32ThemePart GtkWin32ThemePart;
 
 #define GTK_TYPE_WIN32_THEME_PART (_gtk_win32_theme_part_get_type ())
@@ -43,6 +45,10 @@ cairo_pattern_t   *_gtk_win32_theme_part_render   (GtkWin32ThemePart  *part,
 int                _gtk_win32_theme_int_parse     (GtkCssParser      *parser,
                                                   GFile             *base,
                                                   int               *value);
+GtkSymbolicColor  *_gtk_win32_theme_color_parse   (GtkCssParser      *parser);
+gboolean           _gtk_win32_theme_color_resolve (const char        *theme_class,
+                                                  gint               id,
+                                                  GdkRGBA           *color);
 
 G_END_DECLS